#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "./uthash/include/uthash.h"

char *data_in[] = {
        
       
        "Lisi Zhongxing",
        "Wangwu Ailixin",
        "Tim Zhongxing",
        "Zhangsan Huawei"
        // "Tim Huawei",
};

int dataLen = 4;

char* data_in_2[] = {
   
    "Lisi",
    "Wangwu",
    "Tim",
     "Zhangsan",
    "Zhangsan",
    "Tim",
    "Tim",
    
};

int dataLen2 = 7;

struct NameCom {
    char name[100];
    char company[100];
    UT_hash_handle hh;
    };

struct ComVot {
    char com[100];
    int vote;
    UT_hash_handle hh;
    };

int cmp_com (struct ComVot *c, struct ComVot *d) {
    return d->vote - c->vote;
}

int main() {
    char res[100];
    struct NameCom* name_com = NULL;
    struct ComVot* com_vot = NULL;

    for (int i = 0; i < dataLen; ++i) {
        char* name = (char*)malloc(sizeof(char) * 100);
        memset(name, 0, sizeof(char) * 100);
        char* company = (char*)malloc(sizeof(char) * 100);
        memset(company, 0, sizeof(char) * 100);
        sscanf(data_in[i], "%s %s", name, company);

        // printf("%s, %s\n", name, company);
        
        // struct NameCom* tmp = (struct NameCom*)malloc(sizeof(struct NameCom));
        struct NameCom* tmp = NULL;
        HASH_FIND_STR(name_com, name, tmp);

        if (tmp == NULL) {
            struct NameCom* cur = (struct NameCom*)malloc(sizeof(struct NameCom));
            strcpy(cur->name, name);
            strcpy(cur->company, company);
            HASH_ADD_STR(name_com, name, cur);
            printf(" add %s", cur->name);
        } else if (strcmp(tmp->company, company) != 0) {
            printf(" del %s", tmp->name);
            HASH_DEL(name_com, tmp);
            free(tmp);
        }
    }

    for (int i = 0; i < dataLen2; ++i) {
        struct NameCom* tmp = NULL;
        HASH_FIND_STR(name_com, data_in_2[i], tmp);
        if (tmp != NULL) {
            printf("vote %s", tmp->company);
            struct ComVot *com_tmp = NULL;
            HASH_FIND_STR(com_vot, tmp->company, com_tmp);
            if (com_tmp == NULL) {
                printf(" Noinfo");
                struct ComVot *com_cur = (struct ComVot*)malloc(sizeof(struct ComVot));
                strcpy(com_cur->com, tmp->company);
                com_cur->vote = 1;
                HASH_ADD_STR(com_vot, com, com_cur);
                printf(" add %s\n", com_cur->com);
            } else {
                com_tmp->vote += 1;
                printf(" addVote %s\n", com_tmp->com);
            }  
        }        
             
    }

    // struct ComVot *a;
    // for (a = com_vot; a != NULL; a = a->hh.next) {
    //     printf("%s:%d\t", a->com, a->vote);
    // }
    struct ComVot *a, *b;

    HASH_SORT(com_vot, cmp_com);

    int maxVote = 0;
    int maxVoteTime = 0;
    strcpy(res, "NULL");
    HASH_ITER(hh, com_vot, a, b) {
        printf("%s:%d\t", a->com, a->vote);
        if (a->vote > maxVote) {
            strcpy(res, a->com);
            maxVoteTime = 1;
            maxVote = a->vote;
        } else if (a->vote == maxVote) {
            maxVoteTime++;
        } 
        
    }

    printf("%d", maxVoteTime);
    if (maxVoteTime >= 2) {
        strcpy(res, "NULL");
    }

    printf("\n%s\n", res);

    return 0;
}